import {ActivatedRoute, NavigationEnd, Router} from '@angular/router';
import {AlertMessage} from '../../entity/alert-message';
import {MessageService} from '../../service/message.service';
import {formatDate} from '@angular/common';
import {Doc} from '../../entity/doc';
import {Artifact} from '../../entity/artifact';
import {DocService} from '../../service/doc.service';
import {PageVo} from '../../entity/page-vo';
import {PageVoService} from '../../service/page-vo.service';
import {Menu} from '../../entity/menu';
import {Env} from '../../entity/env';
import {Component, Injectable, OnDestroy} from '@angular/core';
import {Subscription} from 'rxjs/index';
import {MenuRoutes} from '../../service/menu-routes';

@Injectable()
export abstract class BaseDocComponent implements OnDestroy, MenuRoutes {
    // 详见https://angular.io/guide/i18n#setting-up-locale
    protected LOCALE = 'en-US';

    docId: string;

    apiId: string;

    apiVersion: string | number;

    mdId: string;

    /**
     * 当前文档
     */
    doc: Doc;

    env: Env;

    artifact: Artifact;

    private envSubscribe: Subscription;

    private readonly routerEventsSubscribe: Subscription;

    protected constructor(protected activatedRoute: ActivatedRoute,
                          protected router: Router,
                          protected pageVoService: PageVoService,
                          protected docService: DocService,
                          protected messageService: MessageService) {
        this.routerEventsSubscribe = router.events.subscribe(val => {
            if (val instanceof NavigationEnd) {
                this.docId = this.activatedRoute.snapshot.paramMap.get('docId');
                this.apiId = this.activatedRoute.snapshot.paramMap.get('apiId');
                this.apiVersion = this.activatedRoute.snapshot.paramMap.get('version');
                this.mdId = this.activatedRoute.snapshot.queryParamMap.get('r');

                if (this.doc && this.doc.artifact.id === this.docId) {
                    this.initDoc();
                } else {
                    docService.getDoc(this.docId, this.apiVersion).subscribe((doc: Doc) => {
                        this.doc = doc;
                        this.initDoc();
                    });
                }
                this.checkVersionChange();
            }
        });
    }

    ngOnDestroy(): void {
        if (this.envSubscribe) {
            this.envSubscribe.unsubscribe();
        }
        if (this.routerEventsSubscribe) {
            this.routerEventsSubscribe.unsubscribe();
        }
    }

    private initDoc() {
        this.initEnv();
        this.onDocReady();
        this.updatePageVo();
    }

    private initEnv() {
        this.envSubscribe = this.docService.getEnv(this.forceFetchEnv()).subscribe(env => {
            this.env = env;
            this.onEnvReady();
        });
    }

    protected onDocReady() {

    }

    protected forceFetchEnv() {
        return false;
    }

    protected onEnvReady() {
    }

    /**
     * 当前用户必须是文档所有者检查，否则会跳转回文档首页
     */
    protected docOwnerCheck() {
        if (!this.docService.isCurrentDocOwner()) {
            // 如果不是当前文档的所有者，则直接跳转回文档首页
            this.router.navigate(['/doc', this.docId]);
        }
    }

    protected getLeftMenuId() {
        let leftMenuId = this.docId;
        if (this.apiVersion) {
            leftMenuId += '_' + this.apiVersion;
        }
        console.log(leftMenuId);
        return leftMenuId;
    }

    getComponent() {
        return this;
    }

    getLeftMenuRoutes(menu: Menu, component): string[] {
        if (this.apiVersion) {
            return ['v', this.apiVersion.toString()];
        }
        return null;
    }

    /**
     * 当前选中的左菜单
     * @returns {string}
     */
    protected getActiveMenuId(): string {
        return null;
    }


    protected setPageVo(basePageVo: PageVo) {

    }

    /**
     * 路由变更
     */
    private updatePageVo(): void {
        if (!this.doc) {
            return;
        }

        const leftMenuId = this.getLeftMenuId();
        const pageVo = this.docService.getBaseDocPageVo(leftMenuId, this);

        // 处理显示状态
        const activeMenuId = this.getActiveMenuId();
        if (activeMenuId) {
            this.setActiveMenu(pageVo.leftMenus, activeMenuId);
        }

        this.setPageVo(pageVo);
        this.pageVoService.setPageVo(pageVo);
    }

    private setActiveMenu(menus: Menu[], activeMenuId: string): boolean {
        if (!menus) {
            return false;
        }
        let active = false;
        menus.forEach(menu => {
            if (menu.id === activeMenuId) {
                menu.active = true;
                active = true;
            } else {
                menu.active = false;
                if (this.setActiveMenu(menu.children, activeMenuId)) {
                    menu.expanding = true;
                }
            }
        });
        return active;
    }

    private checkVersionChange() {
        const messageId = 'old-doc-view';
        if (this.apiVersion) {
            const routLink = [];
            let isVersion = false;
            this.activatedRoute.snapshot.url.forEach(item => {
                if (isVersion) {
                    return;
                }
                if (item.path === 'v') {
                    isVersion = true;
                    return;
                }
                routLink.push(item.path);
            });

            const params = {};
            if (window.location.search) {
                const query = window.location.search.substring(1).split('=');
                for (let i = 0, c = query.length; i < c; ++i) {
                    params[query[i]] = decodeURIComponent(query[i + 1]);
                    ++i;
                }
            }
            this.messageService.removeById(messageId);
            this.messageService.add(<AlertMessage>{
                id: messageId,
                type: 'error',
                link: routLink,
                queryParams: (window.location.search) ? params : null,
                html: `<strong>当前文档是历史版本</strong>v${formatDate(this.apiVersion, 'yyyy-MM-dd HH:mm', this.LOCALE)}, 点击切换最新版本`
            });
        } else {
            this.messageService.removeById(messageId);
        }
    }
}
